
#include <cstring>
#include "Class.h"
#include "common.h"
#include "ObjRange.h"
#include "core.h"
#include "vm.h"

DEFINE_BUFFER_METHOD(Method)

bool ValueIsEqual(Value a, Value b) {
    //类型不同则无须进行后面的比较
    if (a.type != b.type) {
        return false;
    }

    //同为数字,比较数值
    if (a.type == VT_NUM) {
        return a.num == b.num;
    }

    //同为对象,若所指的对象是同一个则返回true
    if (a.objHeader == b.objHeader) {
        return true;
    }

    //对象类型不同无须比较
    if (a.objHeader->type != b.objHeader->type) {
        return false;
    }

    //以下处理类型相同的对象
    //若对象同为字符串
    if (a.objHeader->type == OT_STRING) {
        ObjString *strA = VALUE_TO_OBJSTR(a);
        ObjString *strB = VALUE_TO_OBJSTR(b);
        return (strA->value.length == strB->value.length &&
                memcmp(strA->value.start, strB->value.start, strA->value.length) == 0);
    }

    //若对象同为range
    if (a.objHeader->type == OT_RANGE) {
        ObjRange *rgA = VALUE_TO_OBJRANGE(a);
        ObjRange *rgB = VALUE_TO_OBJRANGE(b);
        return (rgA->from == rgB->from && rgA->to == rgB->to);
    }

    return false;  //其它对象不可比较
}

Class::Class(VM *vm, const char *name, uint32_t fieldNum) {
    auto *objClass = ALLOCATE(vm, Class);

    //裸类没有元类
    objClass->objHeader = *new ObjHeader(vm, OT_CLASS, nullptr);
    objClass->name = ObjString::NewObjString(vm, name, strlen(name));
    objClass->fieldNum = fieldNum;
    objClass->superClass = nullptr;   //默认没有基类
    MethodBufferInit(&objClass->methods);

    this->objHeader = objClass->objHeader;
    this->name = objClass->name;
    this->fieldNum = objClass->fieldNum;
    this->methods = objClass->methods;
    this->superClass = objClass->superClass;

}

//新建一个裸类
Class *Class::NewRawClass(VM *vm, const char *name, uint32_t fieldNum) {
    auto *objClass = ALLOCATE(vm, Class);

    //裸类没有元类
    objClass->objHeader = *new ObjHeader(vm, OT_CLASS, nullptr);
    objClass->name = ObjString::NewObjString(vm, name, strlen(name));
    objClass->fieldNum = fieldNum;
    objClass->superClass = nullptr;   //默认没有基类
    MethodBufferInit(&objClass->methods);

    return objClass;
}

//创建一个类
Class *Class::NewClass(VM *vm, ObjString *className, uint32_t fieldNum, Class *superClass) {
    //10表示strlen(" metaClass"
#define MAX_METACLASS_LEN MAX_ID_LEN + 10
    char newClassName[MAX_METACLASS_LEN] = {'\0'};
#undef MAX_METACLASS_LEN

    memcpy(newClassName, className->value.start, className->value.length);
    memcpy(newClassName + className->value.length, " metaclass", 10);

    //先创建子类的meta类
    Class* metaclass = NewRawClass(vm, newClassName, 0);
    metaclass->objHeader.objClass = vm->classOfClass;

    //绑定classOfClass为meta类的基类
    //所有类的meta类的基类都是classOfClass
    BindSuperClass(vm, metaclass, vm->classOfClass);

    //最后再创建类
    memcpy(newClassName, className->value.start, className->value.length);
    newClassName[className->value.length] = '\0';
    Class* objClass = NewRawClass(vm, newClassName, fieldNum);

    objClass->objHeader.objClass = metaclass;
    BindSuperClass(vm, objClass, superClass);

    return objClass;
}

Class *Class::GetClassOfObj(VM *vm, Value object) {
    switch (object.type) {
        case VT_NULL:
            return vm->nullClass;
        case VT_FALSE:
        case VT_TRUE:
            return vm->boolClass;
        case VT_NUM:
            return vm->numClass;
        case VT_OBJ:
            return VALUE_TO_OBJ(object)->objClass;
        default:
            NOT_REACHED();
    }
    return nullptr;
}
